#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2023/5/13 16:16
# @Author  : SDU Wang Yishuo
# @FileName: status.py
# @Software: PyCharm

import copy


# 状态类
class Status:
    # 传入文法集合，左部-文法映射
    def __init__(self, gras, graMap):
        # 文法集合
        self._gras = copy.deepcopy(gras);
        # 检查
        check = True
        while check:
            # 假设结束
            check = False
            # 遍历状态中每一个文法
            grasList = list(self._gras)

            for gra in grasList:
                # 得到当前文法的方向
                curSym = gra.getCurDire()
                # # 如果这个文法已经clouser过了，继续
                if curSym is None:
                    continue
                # 如果是非终结符
                if curSym[0] == '<':
                    # 遍历所有以该非终结符为左部的文法
                    for g in graMap[curSym]:
                        if not g in self._gras:
                            # 加入这个文法
                            self._gras.add(g)
                            # 继续检查
                            check = True

    # 返回可以前进的方向列表
    # 即该状态下所有文法的当前方向
    def getDire(self):
        dirs = set()
        for gra in self._gras:
            dire = gra.getCurDire()
            # 可以规约就不要添加了
            if dire is not None:
                dirs.add(dire)
        return list(dirs)

    # 向指定的方向前进并返回新的状态
    # 即把该状态中所有当前方向为指定方向的文法进行前进操作，得到一个新的状态
    def forward(self, dire, graMap):

        gramSet = set()
        for g in self._gras:
            if g.getCurDire() == dire:
                temp = g.copy()
                temp.forward()
                gramSet.add(temp)
        return Status(gramSet, graMap)

    # 获取可规约项目列表
    def getRegs(self):
        res = []
        for g in self._gras:
            if g.isReg():
                res.append(g)
        return res

    def __hash__(self):
        return hash(str(self))

    # 判断状态是否相等
    def __eq__(self, other):
        if other is None:
            return False
        return self._gras == other._gras

    # 打印状态
    def __str__(self):
        res = ''
        for gra in self._gras:
            res += str(gra) + '\n'
        return res
    # 打印状态
